package com.pro.dl.dao.impl;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;

import com.pro.dl.dao.service.PersonDao;
import com.pro.dl.exception.AlreadyPresentObject;
import com.pro.dl.exception.PersonAlreadyExists;
import com.pro.dl.exception.StorageException;
import com.pro.dl.exception.UserDoesNotExists;
import com.pro.dl.pojo.Person;
import com.pro.dl.pojo.profile.PersonType;

public class PersonDaoImpl extends GenericDaoImpl implements PersonDao {

	@Override
	public Person searchPersonByUserName(String userName)
			throws StorageException {
		return searchPerson(userName);
	}

	@Override
	public Person searchPersonById(long id) throws StorageException {
		return getObjectById(id, Person.class);
	}

	private Person searchPerson(String userName) throws StorageException {
		return searchUniqueObjectByCriteria(Collections
				.singletonList((Criterion) Restrictions
						.eq("userName", userName)), Person.class);
	}
	

	@Override
	public PersonType getPersonTypeById(long personTypeId) throws StorageException {
		return getObjectById(personTypeId, PersonType.class);
	}

	@Override
	public PersonType searchPersonTypeByName(String type) throws StorageException {
		return searchUniqueObjectByCriteria(Arrays.asList(
				(Criterion) Restrictions.eq("name", type)), PersonType.class );
	}

	@Override
	public Person validateUser(String userName, String token)
			throws StorageException {
		return searchUniqueObjectByCriteria(Arrays.asList(
				(Criterion) Restrictions.eq("userName", userName),
				(Criterion) Restrictions.eq("token", token)), Person.class);
	}

	@Override
	public Person validateQNA(String userName, String question, String answer)
			throws StorageException {

		return searchUniqueObjectByCriteria(Arrays.asList(
				(Criterion) Restrictions.eq("userName", userName),
				(Criterion) Restrictions.eq("secreteQuestion", question),
				(Criterion) Restrictions.eq("secretQuestionAnswer", answer)), Person.class);
	}

	@Override
	public Person validatePassword(String userName, String password)
			throws StorageException {
		return searchUniqueObjectByCriteria(Arrays.asList(
				(Criterion) Restrictions.eq("userName", userName),
				(Criterion) Restrictions.eq("password", password)), Person.class);
	}

	@Override
	public Person savePerson(Person person) throws StorageException,
			PersonAlreadyExists {
		try {
			createObject(person);
		} catch (AlreadyPresentObject e) {
			throw new PersonAlreadyExists(
					"User has already been registered with similar phone or email or username ",
					e);
		}
		return person;
	}

	@Override
	public Person updatePerson(Person person) throws StorageException,
			UserDoesNotExists {
		updateObject(person);
		return person;
	}

	@Override
	public void overridePassword(String userName, String password)
			throws StorageException, UserDoesNotExists {
		Map<String, Object> map = new HashMap<String, Object>(2);
		Person person  = searchPerson(userName);
		if(person  == null){
			throw new UserDoesNotExists("user with username " + userName
					+ " does not exists");
		}
		person.setPassword(password);
		updateObject(person);
	}

}
